Svenska

Frigör kraften i GraphQL Federation med Schema Stitching. Lär dig bygga ett enhetligt GraphQL API från flera tjänster, vilket förbättrar skalbarhet och underhåll.

GraphQL Federation: Schema Stitching - En Omfattande Guide

I det ständigt föränderliga landskapet för modern applikationsutveckling har behovet av skalbara och underhållbara arkitekturer blivit avgörande. Mikrotjänster, med sin inneboende modularitet och oberoende driftsättningsbarhet, har framträtt som en populär lösning. Att hantera ett stort antal mikrotjänster kan dock introducera komplexitet, särskilt när det gäller att exponera ett enhetligt API för klientapplikationer. Det är här GraphQL Federation, och specifikt Schema Stitching, kommer in i bilden.

Vad är GraphQL Federation?

GraphQL Federation är en kraftfull arkitektur som låter dig bygga ett enda, enhetligt GraphQL API från flera underliggande GraphQL-tjänster (som ofta representerar mikrotjänster). Det gör det möjligt för utvecklare att hämta data över olika tjänster som om det vore en enda graf, vilket förenklar klientupplevelsen och minskar behovet av komplex orkestreringslogik på klientsidan.

Det finns två huvudsakliga tillvägagångssätt för GraphQL Federation:

Denna artikel fokuserar på Schema Stitching och utforskar dess koncept, fördelar, begränsningar och praktiska implementering.

Förståelse för Schema Stitching

Schema Stitching är processen att slå samman flera GraphQL-scheman till ett enda, sammanhängande schema. Detta enhetliga schema fungerar som en fasad och döljer komplexiteten hos de underliggande tjänsterna från klienten. När en klient gör en förfrågan till det sammansatta schemat, dirigerar gatewayen intelligent förfrågan till den eller de lämpliga underliggande tjänsterna, hämtar datan och kombinerar resultaten innan de returneras till klienten.

Tänk på det så här: Du har flera restauranger (tjänster) som var och en specialiserar sig på olika kök. Schema Stitching är som en universell meny som kombinerar alla rätter från varje restaurang. När en kund (klient) beställer från den universella menyn, dirigeras beställningen intelligent till rätt restaurangkök, maten förbereds och kombineras sedan till en enda leverans för kunden.

Nyckelkoncept inom Schema Stitching

Fördelar med Schema Stitching

Schema Stitching erbjuder flera övertygande fördelar för organisationer som antar en mikrotjänstarkitektur:

Begränsningar med Schema Stitching

Även om Schema Stitching erbjuder många fördelar är det viktigt att vara medveten om dess begränsningar:

Praktisk implementering av Schema Stitching

Låt oss gå igenom ett förenklat exempel på hur man implementerar Schema Stitching med Node.js och biblioteket graphql-tools (ett populärt val för schema stitching). Detta exempel involverar två mikrotjänster: en Användartjänst och en Produkttjänst.

1. Definiera fjärrschemana

Först definierar du GraphQL-schemana för var och en av fjärrtjänsterna.

Användartjänst (user-service.js):


const { buildSchema } = require('graphql');

const userSchema = buildSchema(`
  type User {
    id: ID!
    name: String
    email: String
  }

  type Query {
    user(id: ID!): User
  }
`);

const users = [
  { id: '1', name: 'Alice Smith', email: 'alice@example.com' },
  { id: '2', name: 'Bob Johnson', email: 'bob@example.com' },
];

const userRoot = {
  user: (args) => users.find(user => user.id === args.id),
};

module.exports = {
  schema: userSchema,
  rootValue: userRoot,
};

Produkttjänst (product-service.js):


const { buildSchema } = require('graphql');

const productSchema = buildSchema(`
  type Product {
    id: ID!
    name: String
    price: Float
    userId: ID!  # Främmande nyckel till Användartjänsten
  }

  type Query {
    product(id: ID!): Product
  }
`);

const products = [
  { id: '101', name: 'Laptop', price: 1200, userId: '1' },
  { id: '102', name: 'Smartphone', price: 800, userId: '2' },
];

const productRoot = {
  product: (args) => products.find(product => product.id === args.id),
};

module.exports = {
  schema: productSchema,
  rootValue: productRoot,
};

2. Skapa Gateway-tjänsten

Skapa nu gateway-tjänsten som kommer att sy ihop de två schemana.

Gateway-tjänst (gateway.js):


const { stitchSchemas } = require('@graphql-tools/stitch');
const { makeRemoteExecutableSchema } = require('@graphql-tools/wrap');
const { graphqlHTTP } = require('express-graphql');
const express = require('express');
const { introspectSchema } = require('@graphql-tools/wrap');
const { printSchema } = require('graphql');
const fetch = require('node-fetch');

async function createRemoteSchema(uri) {
  const fetcher = async (params) => {
    const response = await fetch(uri, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(params),
    });
    return response.json();
  };

  const schema = await introspectSchema(fetcher);
  return makeRemoteExecutableSchema({
    schema,
    fetcher,
  });
}

async function main() {
  const userSchema = await createRemoteSchema('http://localhost:4001/graphql');
  const productSchema = await createRemoteSchema('http://localhost:4002/graphql');

  const stitchedSchema = stitchSchemas({
    subschemas: [
      { schema: userSchema },
      { schema: productSchema },
    ],
    typeDefs: `
      extend type Product {
        user: User
      }
    `,
    resolvers: {
      Product: {
        user: {
          selectionSet: `{ userId }`,
          resolve(product, args, context, info) {
            return info.mergeInfo.delegateToSchema({
              schema: userSchema,
              operation: 'query',
              fieldName: 'user',
              args: {
                id: product.userId,
              },
              context,
              info,
            });
          },
        },
      },
    },
  });

  const app = express();
  app.use('/graphql', graphqlHTTP({
    schema: stitchedSchema,
    graphiql: true,
  }));

  app.listen(4000, () => console.log('Gateway server running on http://localhost:4000/graphql'));
}

main().catch(console.error);

3. Kör tjänsterna

Du måste köra Användartjänsten och Produkttjänsten på olika portar. Till exempel:

Användartjänst (port 4001):


const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { schema, rootValue } = require('./user-service');

const app = express();
app.use('/graphql', graphqlHTTP({
  schema: schema,
  rootValue: rootValue,
  graphiql: true,
}));

app.listen(4001, () => console.log('User service running on http://localhost:4001/graphql'));

Produkttjänst (port 4002):


const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { schema, rootValue } = require('./product-service');

const app = express();
app.use('/graphql', graphqlHTTP({
  schema: schema,
  rootValue: rootValue,
  graphiql: true,
}));

app.listen(4002, () => console.log('Product service running on http://localhost:4002/graphql'));

4. Fråga det sammansatta schemat

Nu kan du fråga det sammansatta schemat via gatewayen (som körs på port 4000). Du kan köra en fråga som denna:


query {
  product(id: "101") {
    id
    name
    price
    user {
      id
      name
      email
    }
  }
}

Denna fråga hämtar produkten med ID "101" och hämtar även den associerade användaren från Användartjänsten, vilket demonstrerar hur Schema Stitching låter dig hämta data över flera tjänster i en enda förfrågan.

Avancerade tekniker för Schema Stitching

Utöver det grundläggande exemplet finns här några avancerade tekniker som kan användas för att förbättra din implementering av Schema Stitching:

Välja mellan Schema Stitching och Apollo Federation

Även om Schema Stitching är ett gångbart alternativ för GraphQL Federation, har Apollo Federation blivit det mer populära valet på grund av sina avancerade funktioner och förbättrade utvecklarupplevelse. Här är en jämförelse av de två tillvägagångssätten:

Funktion Schema Stitching Apollo Federation
Schemadefinition Använder befintligt GraphQL-schemaspråk Använder ett deklarativt schemaspråk med direktiv
Frågeplanering Kräver manuell delegering av förfrågningar Automatisk frågeplanering av Apollo Gateway
Typ-utökningar Begränsat stöd Inbyggt stöd för typ-utökningar
Nyckeldirektiv Stöds inte Använder @key-direktivet för att identifiera entiteter
Distribuerad spårning Kräver manuell implementering Inbyggt stöd för distribuerad spårning
Verktyg och ekosystem Mindre mogna verktyg Mognare verktyg och en stor community
Komplexitet Kan vara komplext att hantera i stora system Designat för stora och komplexa system

När du ska välja Schema Stitching:

När du ska välja Apollo Federation:

Verkliga exempel och användningsfall

Här är några verkliga exempel på hur GraphQL Federation, inklusive Schema Stitching, kan användas:

Bästa praxis för Schema Stitching

För att säkerställa en framgångsrik implementering av Schema Stitching, följ dessa bästa praxis:

Slutsats

GraphQL Federation med Schema Stitching erbjuder ett kraftfullt tillvägagångssätt för att bygga enhetliga API:er från flera tjänster i en mikrotjänstarkitektur. Genom att förstå dess kärnkoncept, fördelar, begränsningar och implementeringstekniker kan du utnyttja Schema Stitching för att förenkla dataåtkomst, förbättra skalbarhet och öka underhållbarheten. Även om Apollo Federation har framstått som en mer avancerad lösning, förblir Schema Stitching ett gångbart alternativ för enklare scenarier eller vid integrering av befintliga GraphQL-tjänster. Överväg noggrant dina specifika behov och krav för att välja det bästa tillvägagångssättet för din organisation.

GraphQL Federation: Schema Stitching - En Omfattande Guide | MLOG